﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XSTDZ.ERP.Core.Repositories;
using XSTDZ.ERP.Domain.Models;
using XSTDZ.ERP.Application.DataContracts;
using AutoMapper;

namespace XSTDZ.ERP.Application.Implements
{
    public class ReceivablePayableServiceImpl : ApplicationServiceBase, IReceivablePayableService
    {
         IRepository<ReceivablePayableBill> _billRepository;
        IRepository<ReceivablePayableRecord> _billItemRepository;
         public ReceivablePayableServiceImpl(IRepositoryContext repositoryContext, IRepository<ReceivablePayableBill> billRepository,IRepository<ReceivablePayableRecord> billItemRepository)
            : base(repositoryContext)
        {
            this._billRepository = billRepository;
            this._billItemRepository = billItemRepository;
        }

        /// <summary>
         /// 生成收付款账单 
        /// </summary>
        /// <param name="billDto"></param>
         internal void CreateReceivablePayable(IList<ReceivablePayableBill> bills)
         {
             if (bills != null && bills.Count() != 0)
             {
                 bills.Each(t=>t.Init());
                 this._billRepository.Add(bills);
             }
         }


         public Guid AddReceivablePayable(ReceivablePayableBillDto billDto)
         {
             var bill = Mapper.Map<ReceivablePayableBillDto, ReceivablePayableBill>(billDto);
             this._billRepository.Add(bill);
             bill.Id = Guid.NewGuid();
             bill.BusinessID = Guid.Empty;
             bill.CreateTime = DateTime.Now;
             this.Context.Commit();
             return bill.Id;
         }
        public bool DeleteReceivablePayable(Guid billId)
         {
             var bill = this._billRepository.GetByKey(billId);
             if (bill.ReceivablePayableRecords != null && bill.ReceivablePayableRecords.Count > 0)
             {
                 return false;
             }
             bill.Deleted = 1;
             if (bill.ReceivablePayableRecords != null && bill.ReceivablePayableRecords.Count > 0)
             {
                 bill.ReceivablePayableRecords.Each(t => t.Deleted = 1);
             }
             this._billRepository.Update(bill);
             this.Context.Commit();
             return true;
         }

         public void UpdateReceivablePayable(ReceivablePayableBillDto billDto)
         {
             throw new NotImplementedException();
         }

         public Guid AddReceivablePayableDetail(ReceivablePayableRecordDto billItemDto)
         {
             var bill = this._billRepository.GetByKey(billItemDto.ReceivablePayableBillID);
             #region 计算收付款总额
             if (bill.BillClassify)//付款
             {
                 bill.BillPay = (bill.BillPay ?? 0m) +billItemDto.PaidMoney;//付款
                 bill.BillPayPft = (bill.BillPayPft??0m) + billItemDto.OmitMoney;//优惠
             }
             else//收款
             {
                 bill.BillReceiv = (bill.BillReceiv ?? 0m) + billItemDto.ReceivedMoney;//收款
                 bill.BillReceivPft = (bill.BillReceivPft??0m) + billItemDto.ReceivedMoneyPft;//优惠
             }
             #endregion
             var item = Mapper.Map<ReceivablePayableRecordDto, ReceivablePayableRecord>(billItemDto);
             item.Init();
             this._billItemRepository.Add(item);
             this._billRepository.Update(bill);
             this.Context.Commit();
             return bill.Id;
         }
         public Guid AddReceivablePayableDetail(IList<Guid> billIds, ReceivablePayableRecordDto billItemDto)
         {
             var item = Mapper.Map<ReceivablePayableRecordDto, ReceivablePayableRecord>(billItemDto);

            
             var rpRecords = new List<ReceivablePayableRecord>();

             var productCheckBills = this._billRepository.GetAll(t => billIds.Contains(t.Id));
             decimal count = (decimal)productCheckBills.Count();

             #region 计算分个单据的全收付款
             
             
             productCheckBills.Each(t => {
                 #region 计算收付款总额
                 var rprd=item.Clone(item);
                 if (t.BillClassify)//付款
                 {
                     t.BillPayPft = (t.BillPayPft ?? 0m) + (billItemDto.OmitMoney ?? 0m) / count;//优惠
                     t.BillPay = t.BillPayable - (t.BillPay ?? 0m) - t.BillPayPft;//付款

                     #region 生成收付款明细
                     rprd.PaidMoney = t.BillPay ?? 0m;//付款
                     rprd.OmitMoney = (billItemDto.OmitMoney ?? 0m) / count;//优惠

                     #endregion
                 }
                 else//收款
                 {
                     t.BillReceivPft = (t.BillReceivPft ?? 0m) + (billItemDto.ReceivedMoneyPft ?? 0m) / count;//优惠
                     t.BillReceiv = t.BillReceivable - (t.BillReceiv ?? 0m) - t.BillReceivPft;//收款

                     #region 生成收付款明细
                     rprd.ReceivedMoney = t.BillReceiv ?? 0m;//付款
                     rprd.ReceivedMoneyPft = (billItemDto.ReceivedMoneyPft ?? 0m) / count;//优惠

                     #endregion
                 }
                 rprd.ReceivablePayableBillID = t.Id;
                 rpRecords.Add(rprd.Init());
                 #endregion
             });

             #endregion

             this._billItemRepository.Add(rpRecords);
             this._billRepository.Update(productCheckBills);
             this.Context.Commit();

             return Guid.Empty;
         }

         public void UpdateReceivablePayableDetail(ReceivablePayableRecordDto billItemDto)
         {
             throw new NotImplementedException();
         }

         public void DeleteReceivablePayable(IList<Guid> billIds)
         {
             throw new NotImplementedException();
         }

         public void DeleteReceivablePayableItem(IList<Guid> billItemIds)
         {
             throw new NotImplementedException();
         }
        public ReceivablePayableBillDto GetReceivablePayableBill(Guid billId)
         {
             var productCheckBill= this._billRepository.GetByKey(billId);
             return Mapper.Map<ReceivablePayableBill, ReceivablePayableBillDto>(productCheckBill);
         }
        public IList<ReceivablePayableBillDto> GetReceivablePayableBills(IList<Guid> billIds)
        {
            var productCheckBills = this._billRepository.GetAll(t => billIds.Contains(t.Id));
            return Mapper.Map<IList<ReceivablePayableBill>, IList<ReceivablePayableBillDto>>(productCheckBills.ToList());
        }
         public IList<ReceivablePayableBillDto> getReceivablePayableBills(out int recordCounts, int index, int pageSize)
         {
             recordCounts = 0;

             var orderby = new OrderByParameter<ReceivablePayableBill>(m => m.CreateTime, SortOrder.Descending);
             var productCheckBills = this._billRepository.GetAll(index, pageSize, new[] { orderby });

             var rpblst= Mapper.Map<IList<ReceivablePayableBill>, IList<ReceivablePayableBillDto>>(productCheckBills.ToList());
             foreach (var item in productCheckBills)
             {
                 foreach (var r in rpblst)
                 {
                     if (r.ID == item.Id)
                     {
                         r.LinkmanName = item.ClientInfo.ClientLinks.Where(t=>t.Id==r.Linkman_ID).Select(t => t.LinkManNmae).FirstOrDefault<string>();
                         break;
                     }
                 }
             }
             return rpblst;
         }

         public IList<ReceivablePayableRecordDto> getReceivablePayableBillDetails(Guid billId)
         {
             throw new NotImplementedException();
         }

         public void ConvertReturnBillDeleteState(Guid returnBillId)//不准操作这个单据
         {
             throw new NotImplementedException();
             //var pbill = this._billRepository.GetByKey(returnBillId);
             //pbill.Deleted = 1;
             //pbill.ReceivablePayableRecords.Each(d => { d.Deleted = 1; });
             //this._billRepository.Update(pbill);
             //this.Context.Commit();
         }

         public void ConvertReturnBillDeleteState(Guid returnBillId, IEnumerable<Guid> returnBillDetailIds)
         {
             decimal sjsum = 0;
             decimal yhsum = 0;
             var pbill = this._billRepository.GetByKey(returnBillId);
             pbill.ReceivablePayableRecords.Each(d =>
             {
                 if (returnBillDetailIds.Contains(d.Id))
                 {
                     d.Deleted = 1;

                     if (!pbill.BillClassify)//收款
                     {
                         sjsum +=d.ReceivedMoney;
                         yhsum += d.ReceivedMoneyPft??0m;
                     }
                     else //付款
                     {
                         sjsum += d.PaidMoney;
                         yhsum += d.OmitMoney??0m;
                     }
                 }
             });
             if (!pbill.BillClassify)//收款
             {
                 pbill.BillReceiv=pbill.BillReceiv - sjsum;
                 pbill.BillReceivPft = pbill.BillReceivPft - yhsum;
             }
             else //付款
             {
                 pbill.BillPay = pbill.BillPay - sjsum;
                 pbill.BillPayPft = pbill.BillPayPft - yhsum;
             }
             this._billRepository.Update(pbill);
             this.Context.Commit();
         }


         public  ReceivablePayableRecordDto ReceivablePayableRecord(Guid Id)
         {
             var productCheckBill = this._billItemRepository.GetByKey(Id);
             return Mapper.Map<ReceivablePayableRecord, ReceivablePayableRecordDto>(productCheckBill);
         }





        
    }
}
